﻿using GeneralTheGame;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeamWork.Dig;

class FinishedGame
{
    static string DetermineCombinationName(int index)
    {
        string combinationName = "";
        switch (index)
        {
            case 0:
                combinationName = "Ones";
                break;
            case 1:
                combinationName = "Twos";
                break;
            case 2:
                combinationName = "Threes";
                break;
            case 3:
                combinationName = "Fours";
                break;
            case 4:
                combinationName = "Fives";
                break;
            case 5:
                combinationName = "Sixes";
                break;
            case 6:
                combinationName = "One pair";
                break;
            case 7:
                combinationName = "Two pairs";
                break;
            case 8:
                combinationName = "Three of a kind";
                break;
            case 9:
                combinationName = "Four of a kind";
                break;
            case 10:
                combinationName = "Full House";
                break;
            case 11:
                combinationName = "Small Straight";
                break;
            case 12:
                combinationName = "Large Straight";
                break;
            case 13:
                combinationName = "Chance";
                break;
            case 14:
                combinationName = "Generale";
                break;
            default:
                break;
        }

        return combinationName;
    }

    static void PrintAvailableCombinations(int xPos, int yPos, List<int> scoreList, Player currentPlayer)
    {
        Console.SetCursorPosition(xPos, yPos);
        for (int i = 0; i < scoreList.Count; i++)
        {
            int playerCombinationIndex = i;
            if (i > 5)
            {
                playerCombinationIndex++;
            }

            if (currentPlayer.PlayerCombinations[playerCombinationIndex] == true)
            {
                continue;
            }

            string combinationName = DetermineCombinationName(i);

            Console.WriteLine("{0} - {1}: {2} points",i + 1 , combinationName, scoreList[i]);
        }
    }

    static List<string> combinationList = new List<string>()
    {
        "1", // ones
        "2", // twos
        "3", // threes
        "4", // fours
        "5", // fives
        "6", // sixes
        "7", // one pair
        "8", // two pairs
        "9", // three of a kind
        "10", // four of a kind
        "11", // full house
        "12", // small straight
        "13", // large straight
        "14", // chance
        "15" // generale
    };


    // Command parser, the main function which determines what function to call and when
    // Returns byte which work instead of boolean values
    // -1 means end command is passed and the program should stop execution
    // 0 means that there is an unrecognized command passed in or an error in execution and the player should repeat
    // 1 means that execution finished successfully
    static int ParseCommand(string command, Player currentPlayer, List<int> scoreList = null)
    {
        string[] split = command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

        try
        {
            switch (split[0])
            {
                case "roll":
                    if (split.Length == 1)
                    {
                        currentPlayer.RollAllDice();

                        int[] getThrows = new int[5];
                        for (int i = 0; i < getThrows.Length; i++)
                        {
                            getThrows[i] = currentPlayer.PlayerDice[i].GetLastThrow();
                        }
                        Print.RowPrint(getThrows);

                        return 1;
                    }
                    else
                    {

                        var diceToRoll = new List<int>();

                        for (int i = 1; i < split.Length; i++)
                        {
                            diceToRoll.Add(int.Parse(split[i]));
                        }

                        currentPlayer.ThrowDice(diceToRoll);

                        try
                        {
                            int[] getThrows = new int[5];
                            for (int i = 0; i < getThrows.Length; i++)
                            {
                                getThrows[i] = currentPlayer.PlayerDice[i].GetLastThrow();
                            }
                            Print.RowPrint(getThrows);
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            Console.WriteLine("You have to throw all dice first!");
                            return 0;
                        }

                        return 1;
                    }
                case "end":
                    return -1;
                default:
                    if (!combinationList.Contains(command))
                    {
                        throw new ArgumentException("Unrecognized command!");
                    }
                    else
                    {
                        int indexToAdd = combinationList.IndexOf(command);
                        bool flag = currentPlayer.SetPlayerCombination(indexToAdd, scoreList[indexToAdd]);
                        if (flag == false)
                        {
                            return 0;
                        }
                        return 2;
                    }
            }
        }
        catch (IndexOutOfRangeException)
        {
            Console.WriteLine("You must enter a valid command!");
            return 0;
        }
    }

    static void Main()
    {
        int numberOfPlayers;
        int.TryParse(Console.ReadLine(), out numberOfPlayers);
        Player[] players = new Player[numberOfPlayers];

        for (int i = 0; i < numberOfPlayers; i++)
        {
            string username = Console.ReadLine();
            players[i] = new Player(username, ConsoleColor.Green);
        }

        for (int k = 0; k < 16; k++)
        {
            for (int i = 0; i < numberOfPlayers; i++)
            {
                bool breakflag = false;
                for (int j = 0; j < 4; j++)
                {
                    if (breakflag)
                    {
                        break;
                    }

                    Console.WriteLine("{0}'s {1} turn!", players[i].PlayerName, j);
                    
                    string command = "";
                    int result = 0;

                    var scoreList = new List<int>();
                    if (j == 0)
                    {
                        result = ParseCommand("roll", players[i], null);
                        scoreList = CombinationDetection.DetectCombinations(players[i].PlayerDice);
                        Console.WriteLine("Available combinations");
                        PrintAvailableCombinations(0, 10, scoreList, players[i]);
                    }
                    else
                    {
                        command = Console.ReadLine().ToLower();
                    }

                    if (j == 3 && command.Contains("roll"))
                    {
                        Console.WriteLine("This is your last turn!");
                        Console.WriteLine("You must enter a combination!");
                        while (command.Contains("roll"))
                        {
                            command = Console.ReadLine().ToLower();
                        }
                    }

                    if (command.Contains("roll") || command.Contains("end") && j != 0)
                    {
                        result = ParseCommand(command, players[i], null);
                        scoreList = CombinationDetection.DetectCombinations(players[i].PlayerDice);
                        Console.WriteLine("Available combinations");
                        PrintAvailableCombinations(0, 10, scoreList, players[i]);
                    }
                    else if (j != 0)
                    {
                        scoreList = CombinationDetection.DetectCombinations(players[i].PlayerDice);
                        result = ParseCommand(command, players[i], scoreList);
                    }

                    if (result == -1)
                    {
                        return;
                    }
                    else if (result == 2)
                    {
                        break;
                    }

                    else if (result == 0)
                    {
                        while (result == 0)
                        {
                            command = Console.ReadLine();
                            if (j == 3 && command.Contains("roll"))
                            {
                                result = 0;
                            }
                            else
                            {
                                result = ParseCommand(command, players[i], scoreList);
                                if (result == 2)
                                {
                                    breakflag = true;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
